#include <iostream>
#include <cmath>
#include <vector>
#include <fstream>
#include <iomanip>
using namespace std;
#define fh 30
#define l 181

double pi = atan(1.0) * 4;
double fhi = (fh * pi) / 180;
double u = sin(fhi);
double t = cos(fhi);

// 设置种子值
double p_0_0 = 1;
double p_1_0 = sqrt(3) * t;
double P_1_1 = sqrt(3) * u;

// 展示dp的值，测试使用
void show_dp(vector<vector<int>> dp)
{

    for (int i = 0; i <= dp.size(); i++)
    {
        for (int j = 0; j <= i; j++)
        {
            cout << dp[i][j] << " ";
        }
        cout << endl;
    }
}

// 对动态二维数组初始化，运用指针传址
void chushi_dp(vector<vector<double>> *dp)
{
    (*dp).resize(l);
    // 初始化
    // 平方使用pow( , )

    (*dp)[0].push_back(p_0_0);
    (*dp)[1].push_back(p_1_0);
    (*dp)[1].push_back(P_1_1);

    // 初始化动态数组(*dp)
    for (int i = 2; i < l; i++)
    {
        (*dp)[i].resize(i + 1, 0);
    }
}

// 进行算法向前列运算，使用指针传值
void push_forward(vector<vector<double>> *dp)
{

    // 求出每列前两个数dp[i][i - 1]，dp[i][i]
    for (int i = 2; i < l; i++)
    {
        double f_i = i;
        double x_duijiaoxian1 = u * sqrt((2 * f_i + 1) / (2 * f_i));
        double x_duijioaoxian2 = t * sqrt(2 * i + 1);
        (*dp)[i][i - 1] = x_duijioaoxian2 * (*dp)[i - 1][i - 1];
        (*dp)[i][i] = x_duijiaoxian1 * (*dp)[i - 1][i - 1];
    }

    // 列递推 m为列 n为行
    for (int m = 0; m < l; m++)
    {
        for (int n = 2 + m; n < l; n++)
        {
            double x1_a = (2 * n - 1) * (2 * n + 1);
            double x2_a = (n - m) * (n + m);
            double a_n_m = sqrt(x1_a / x2_a) * t;
            double x1_b = (2 * n + 1) * (n + m - 1) * (n - m - 1);
            double x2_b = (2 * n - 3) * (n + m) * (n - m);
            double b_n_m = sqrt(x1_b / x2_b);
            (*dp)[n][m] = a_n_m * (*dp)[n - 1][m] - b_n_m * (*dp)[n - 2][m];
        }
    }
}

// 输出dp数据文件
void shuchu_csv(vector<vector<double>> *dp, string file_name)
{
    ofstream p;
    p.open(file_name, ios::out | ios::trunc);                       // 打开文件路径
    p << "l" << "  " << "m" << "  " << setw(20) << "P_l_m" << endl; // 输入内容，注意要用逗号，隔开
    for (int i = 0; i <= (*dp).size(); i++)
    {
        for (int j = 0; j <= i; j++)
        {
            p << i << "  " << j << "  " << setw(20) << setiosflags(ios::fixed) << setprecision(16) << (*dp)[i][j] << endl;
        }
        p << endl;
    }
    p.close();
}
